根据经验,用Python运行机器学习包含了3个步骤:
1. 获取数据
2. 建立机器学习模型
3. 优化机器学习模型
1.目标
我们有2008~2018年的兽医数据集,它包含了动物(狗、猫和雪貂)的注册信息。
如上图,数据集特征包含了时间戳、动物名称、体重(单位Kg)、表皮病学水平、是否有李氏杆菌病。
表皮病学水平的检测是非常昂贵的,且对动物可能有伤害,因此我们的目标是建立机器模型,通过其他特征预测表皮病学水平,从而防止动物受到伤害并能节约成本。
2.你需要准备什么
任何版本的Python(https://www.python.org/downloads/)
Pip(https://www.makeuseof.com/tag/install-pip-for-python/)
安装Sklearn ,Panda,openblender(利用Pip)
pip install pandas OpenBlender scikit-learn
步骤1:获取数据
导入将要使用的Python库:
import OpenBlender
import pandas as pd
import numpy as np
import json
import sklearn
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error
我们通过OpenBlender API获取数据。您需要在https://www.openblender.io中创建一个acount账户来获得一个令牌和user_id(它是免费的)
首先,我们定义参数(在本例中它只是数据集的id):
# It only contains the id, we'll add more parameters later.
parameters = {'token' : 'YOUR_TOKEN','id_user' : 'YOUR_USER_ID','id_dataset':'5db079199516296099c9fb1e'
}
数据转换为dataframe格式:
# This function pulls the data and orders by timestamp
def pullObservationsToDF(parameters):action = 'API_getObservationsFromDataset'df = pd.read_json(json.dumps(OpenBlender.call(action,parameters)['sample']), convert_dates=False,convert_axes=False) .sort_values('timestamp', ascending=False)df.reset_index(drop=True, inplace=True)return df
df_vet = pullObservationsToDF(parameters)
查看返回的dataframe数据:
print(df_vet.shape)
df_vet.head()
如上图,我们有800个数据,5个特征。
步骤2:建立机器学习模型
我们首先观察表皮病学水平和体重的关系:
%matplotlib inline
df_vet.plot.scatter('epidermiology_level', 'weight_in_kg')
由上图可知,表皮病学水平和体重呈负相关的关系。
我们首先用简单的线性回归模型来学习:
每个点的误差是给定输入值x,预测值和真实值的距离,最小化该误差来选择a和b。
通过数据集构建线性回归模型的代码:
# First we declare it
regr = LinearRegression()
# Then we fit (or train) it to relate epidermiology with weight
regr.fit(df_vet[['weight_in_kg']], df_vet[['epidermiology_level']])
# Let's take a look at the intercpt (Our 'a')
print(regr.intercept_)
# And the slope (Our 'b')
print(regr.coef_)
回归模型系数a和b的结果:
把该模型添加到上图:
axes = df_vet.plot.scatter('epidermiology_level', 'weight_in_kg')
x_vals = np.array(axes.get_xlim())
y_vals = 37.01155578 + -0.47164364 * x_vals
axes.plot(x_vals, y_vals, '-')
数据集划分为训练集和测试集,测试集的作用是检测机器学习模型的泛化水平:
# First we define 'X' and 'y'
X = df_vet[['weight_in_kg']]
y = df_vet[['epidermiology_level']]
# Then we separate 500 to train
X_train = X[:500]
y_train = y[:500]
print("Train X and y:")
print(X_train.shape)
print(y_train.shape)
# And 300 to test
X_test = X[500:]
y_test = y[500:]
print("Test X and y:")
print(X_test.shape)
print(y_test.shape)
我们利用均方误差(MSE)来测试模型的泛化水平:
# First we traqin the model with the Test Set
lm = LinearRegression()
lm.fit(X_test, y_test)
# Then we generate predictions and compare to ‘y’ test
predictions = lm.predict(X_test)
mean_squared_error(y_test, predictions)
测试集的均方误差:
输出预测值和真实值结果:
df_preds_res = pd.DataFrame({'y_test':y_test['epidermiology_level'], 'y_pred':pred[:,0]})
df_preds_res.head(15)
现在让我们看看是否可以通过增加输入变量来优化该模型。
步骤3:优化ML模型
线性回归的输入值一般是数值型的,我们首先将特征'animal'和'has_listeriosis'转换为数值类型。
转换前的数据:
转换代码:
#We add the 'categorical_treatment' parameter and pull again.
parameters = {'token' : 'YOUR_TOKEN','id_user' : 'YOUR_USER_ID','id_dataset':'5db079199516296099c9fb1e','categorical_treatment': {"treatment" : "convert_to_numeric", "exclude" : ["weight_in_kg"]}
}
df_vet_numerical = pullObservationsToDF(parameters)
转换后的数据:
为了获得更多有用的特征,我们将日期细分为许多与时间相关的特征,如星期几,几月份。
parameters = {'token' : 'YOUR_TOKEN','id_user' : 'YOUR_USER_ID','id_dataset':'5db079199516296099c9fb1e','categorical_treatment': {"treatment" : "convert_to_numeric",'exclude' : ["weight_in_kg"]},'date_treatment':{"treatment":"breakdown"}
}
df_vet_numerical = pullObservationsToDF(parameters)
df_vet_numerical.columns
特征有:
数据集划分为训练集和测试集:
target_variable = 'epidermiology_level'
# First we define ‘X’ and ‘y'
X = df_vet_numerical.loc[:, df_vet_numerical.columns != target_variable].values
y = df_vet_numerical.loc[:,[target_variable]].values
# Then we separate 500 to train
X_train = X[:500]
y_train = y[:500]
print("Train X and y:")
print(X_train.shape)
print(y_train.shape)
# And 300 to test
X_test = X[500:]
y_test = y[500:]
print("Test X and y:")
print(X_test.shape)
print(y_test.shape)
现在我们有30个特征构建回归模型,表达式为:
对比单变量的线性回归模型,看看MSE是否有降低。
# First we traqin the model with the Test Set
lm = LinearRegression()
lm.fit(X_test, y_test)
# Then we generate predictions and compare to ‘y’ test
pred = lm.predict(X_test)
mean_squared_error(y_test, pred)
由结果可知,多变量的MSE降低了,因此多变量的模型性能更好了。
输出预测值和真实值。
df_preds_res = pd.DataFrame({'y_test':y_test[:,0], 'y_pred':pred[:,0]})
df_preds_res.head(15)
推荐阅读
干货 | 清晰易懂的机器学习算法原理介绍
欢迎扫码关注: